package org.xxpay.pay.channel.nps;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Component;
import org.xxpay.common.http.HttpRequestTemplate;
import org.xxpay.common.util.DateUtils;
import org.xxpay.common.util.Util;
import org.xxpay.common.util.XML;
import org.xxpay.common.util.str.StringUtils;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.entity.TransOrder;
import org.xxpay.pay.channel.BaseTrans;
import org.xxpay.pay.channel.nps.util.EncryptUtil;
import org.xxpay.pay.channel.nps.util.NpsBank;

import java.util.Date;
import java.util.Map;

@Component
public class NpsTransService extends BaseTrans {
    private final static String logPrefix = "【nps】";
    // 下单地址
    public static final String ORDER_CREATE_STR = "/pay.cgi";
    // 查单地址
    private final static String ORDER_QUERY_STR = "/query.cgi";

    @Override
    public String getChannelName() {
        return NpsConfig.CHANNEL_NAME;
    }

    @Override
    public JSONObject balance(String payParam) {
        JSONObject retObj = buildRetObj();
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, "没有余额查询接口");
        return retObj;
    }
    /**
     * 代付订单
     *
     * @param transOrder
     * @return
     */
    @Override
    public JSONObject trans(TransOrder transOrder) {
        JSONObject retObj = buildRetObj();
        NpsConfig config = new NpsConfig(getTransParam(transOrder));
        Map<String, Object> params = Maps.newHashMap();
        getTradeData(params,transOrder,config);
        _log.info("{}申请代付请求参数：{}", logPrefix, params.toString());
        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(null);
        String restData = requestTemplate.postForObject(getReqUrl(config.getRequestUrl(),ORDER_CREATE_STR), params, String.class);
        _log.info("{}代付请求响应参数：{}", logPrefix, restData);
        JSONObject origin = XML.toJSONObject(restData);
        retObj.put("isSuccess", false);
        retObj.put("transOrderId", transOrder.getTransOrderId());
        if(StringUtils.equals(origin.getString("RESP_CODE"),"0000") || StringUtils.equals(origin.getString("RESP_CODE"),"00")  || StringUtils.equals(origin.getString("RESP_CODE"),"0100")){
            retObj.put("channelOrderNo", "");
            retObj.put("isSuccess", true);
            // 1. 处理中 2. 成功 3. 失败
            retObj.put("status", 1);
            return retObj;
        }
        // 1. 处理中 2. 成功 3. 失败
        retObj.put("status", 3);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, "下单失败[" + origin.getString("info") + "]");
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        return retObj;
    }

    /**
     * 订单查询接口
     *
     * @param transOrder
     * @return
     */
    @Override
    public JSONObject query(TransOrder transOrder) {
        NpsConfig config = new NpsConfig(getTransParam(transOrder));
        Map<String, Object> params = Maps.newHashMap();
        params.put("ORDER_ID", transOrder.getTransOrderId());
        params.put("USER_TYPE", "02");
        params.put("USER_ID", config.getMchId());
        params.put("SIGN_TYPE", "03");
        String signStr= "ORDER_ID=" + params.get("ORDER_ID")
                +"&USER_TYPE=" + params.get("USER_TYPE")
                +"&USER_ID=" + params.get("USER_ID")
                +"&SIGN_TYPE=" + params.get("SIGN_TYPE")
                + "&"+ config.getPrivateKey();

        System.out.println("支付请求："+signStr);
        String SIGN= EncryptUtil.MD5(EncryptUtil.MD5(signStr, 1).toUpperCase()+config.getPrivateKey(),0).toUpperCase();
        params.put("SIGN", SIGN);
        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(null);
        String restData = requestTemplate.postForObject(getReqUrl(config.getRequestUrl(),ORDER_QUERY_STR), params, String.class);
        _log.info("{}代付查询请求响应参数：{}", logPrefix, restData);
        JSONObject origin = XML.toJSONObject(restData);
        JSONObject retObj = buildRetObj();
        if (origin.get("STATUS").equals("1")){
            retObj.put("isSuccess", true);
            retObj.put("transOrderId", origin.getString("ORDER_ID"));
            retObj.put("channelObj", origin);
            if (origin.get("RESP_CODE").equals("0000")){
                // 1. 处理中 2. 成功 3. 失败
                retObj.put("status", 2);
                return retObj;
            }
            if (origin.get("RESP_CODE").equals("0100")){
                // 1. 处理中 2. 成功 3. 失败
                retObj.put("status", 1);
                return retObj;
            }
            retObj.put("status", 3);
            return retObj;
        }
        retObj.put("status", 3);
        retObj.put("channelObj", origin);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, "查单失败[" + origin.getString("RESP_DESC") + "]");
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        return retObj;
    }


    //获取代付下单报文
    private Map<String, Object> getTradeData(Map<String, Object> params, TransOrder transOrder,NpsConfig config){
        params.put("ORDER_ID", transOrder.getTransOrderId());
        params.put("ORDER_AMT", Util.conversionYuanAmount(transOrder.getAmount()));
        params.put("ORDER_TIME", DateUtils.YYYYMMDDHHMMSS.format(new Date()));
        params.put("USER_TYPE", "02");
        params.put("USER_ID", config.getMchId());
        params.put("SIGN_TYPE", "03");
        params.put("BUS_CODE", config.getPayMode());
        params.put("BANK_CODE", NpsBank.valueOf(transOrder.getBankCode()).getCode());
        params.put("ACCOUNT_NO", transOrder.getAccountNo());
        params.put("BANK_NAME", NpsBank.valueOf(transOrder.getBankCode()).getName());
        params.put("ACCOUNT_NAME", transOrder.getAccountName());
        params.put("SIGN", getSign(params,config));
        return params;
    }
        /**
         * 签名
         * @param params
         * @return
         */
        private String getSign (Map<String, Object> params, NpsConfig npsConfig) {
            String signStr= "ORDER_ID="+params.get("ORDER_ID")
                    +"&ORDER_AMT="+params.get("ORDER_AMT")
                    +"&ORDER_TIME="+params.get("ORDER_TIME")
                    +"&USER_TYPE="+params.get("USER_TYPE")
                    +"&USER_ID="+params.get("USER_ID")
                    +"&SIGN_TYPE="+params.get("SIGN_TYPE")
                    +"&BUS_CODE=" +params.get("BUS_CODE")
                    +"&BANK_CODE="+params.get("BANK_CODE")
                    +"&ACCOUNT_NO="+params.get("ACCOUNT_NO")
                    + "&"+npsConfig.getPrivateKey();

            String sign= EncryptUtil.MD5(EncryptUtil.MD5(signStr, 1).toUpperCase()+npsConfig.getPrivateKey(),0).toUpperCase();
            _log.info("{}代付签名结果:{}", logPrefix, sign);
            return sign;
        }
}
